package models

import (
	"fmt"
	"github.com/goravel/framework/contracts/database/factory"
	"github.com/goravel/framework/database/orm"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/support/carbon"
	. "goravel/app/models/common"
	"goravel/database/factories"
)

type Historytrack struct {
	orm.Model
	DeviceID    uint            `gorm:"column:device_id;comment:'设备id'" form:"device_id" json:"device_id"`
	LocationAt  carbon.DateTime `gorm:"column:location_at;comment:'定位时间'" form:"location_at" json:"location_at"`
	Coordinates CoordRes        `gorm:"column:coordinates;comment:'坐标'" form:"coordinates" json:"coordinates"`
	Address     string          `gorm:"column:address;comment:'地址'" form:"address" json:"address"`
	Device      Device
}

func (*Historytrack) Factory() factory.Factory {
	return &factories.HistorytrackFactory{}
}

// CalcDistance 计算距离geometry
func (*Historytrack) CalcDistance(models []Historytrack) float64 {
	distanceAll := 0.0
	//这里需要考虑单数的情况
	if len(models)%2 != 0 {
		//1、先处理双数
		lastModel := models[len(models)-1]
		endModel := models[len(models)-2]
		models = models[:len(models)-1]
		for i := 0; i < len(models); i += 2 {
			var distance float64
			models_1 := models[i]
			models_2 := models[i+1]
			querySql := fmt.Sprintf("SELECT "+
				"ST_Distance_Sphere("+
				"ST_GeomFromText('POINT(%v %v)'),"+
				"ST_GeomFromText('POINT(%v %v)')"+
				") AS distance;", models_1.Coordinates.Coordinates[0], models_1.Coordinates.Coordinates[1], models_2.Coordinates.Coordinates[0], models_2.Coordinates.Coordinates[1])
			facades.Orm().Query().Raw(querySql).Select("distance").Pluck("distance", &distance)
			distanceAll += distance / 1000
		}
		//2、再处理单数，双数的最后一个，与最后一个单数的距离

		querySql := fmt.Sprintf("SELECT "+
			"ST_Distance_Sphere("+
			"ST_GeomFromText('POINT(%v %v)'),"+
			"ST_GeomFromText('POINT(%v %v)')"+
			") AS distance;", lastModel.Coordinates.Coordinates[0], lastModel.Coordinates.Coordinates[1], endModel.Coordinates.Coordinates[0], endModel.Coordinates.Coordinates[1])

		var distanceAdd float64

		facades.Orm().Query().Raw(querySql).Select("distance").Pluck("distance", &distanceAdd)
		distanceAll += distanceAdd

	} else {
		for i := 0; i < len(models); i += 2 {
			var distance float64
			models_1 := models[i]
			models_2 := models[i+1]
			querySql := fmt.Sprintf("SELECT "+
				"ST_Distance_Sphere("+
				"ST_GeomFromText('POINT(%v %v)'),"+
				"ST_GeomFromText('POINT(%v %v)')"+
				") AS distance;", models_1.Coordinates.Coordinates[0], models_1.Coordinates.Coordinates[1], models_2.Coordinates.Coordinates[0], models_2.Coordinates.Coordinates[1])
			fmt.Println(querySql)
			facades.Orm().Query().Raw(querySql).Select("distance").Pluck("distance", &distance)
			distanceAll += distance / 1000
		}
	}

	return distanceAll
}
